package com.openyelp.data.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ada.common.security.Digests;
import com.ada.common.security.Encodes;
import com.openyelp.data.core.Finder;
import com.openyelp.data.core.Pagination;
import com.openyelp.data.core.Updater;
import com.openyelp.data.dao.UserDao;
import com.openyelp.data.entity.UserRole;
import com.openyelp.data.entity.User;
import com.openyelp.data.service.UserService;

@Service
@Transactional
public class UserServiceImpl implements UserService {
	@Transactional(readOnly = true)
	public Pagination getPage(int pageNo, int pageSize) {
		Pagination page = dao.getPage(pageNo, pageSize);
		return page;
	}

	@Transactional(readOnly = true)
	public User findById(Long id) {
		User entity = dao.findById(id);
		return entity;
	}

	@Transactional
	public User save(User bean) {
		User user=new User();
		List<User> us = dao.findByProperty("username", bean.getUsername());
		if(us!=null&&us.size()>0){
			user.setId(-1l);
		}else{
			entryptPassword(bean);
			user=dao.save(bean);
		}
		return user;
	}

	@Transactional
	public User update(User bean) {
		Updater<User> updater = new Updater<User>(bean);
		bean = dao.updateByUpdater(updater);
		return bean;
	}

	@Transactional
	public User deleteById(Long id) {
		User bean = dao.deleteById(id);
		return bean;
	}

	@Transactional
	public User[] deleteByIds(Long[] ids) {
		User[] beans = new User[ids.length];
		for (int i = 0, len = ids.length; i < len; i++) {
			beans[i] = deleteById(ids[i]);
		}
		return beans;
	}

	private UserDao dao;

	@Autowired
	public void setDao(UserDao dao) {
		this.dao = dao;
	}

	@Transactional
	@Override
	public User addRole(Long id, UserRole bean) {
		User entity = dao.findById(id);
		entity.getRoles().add(bean);
		return entity;
	}

	@Override
	public User findByUsername(String username) {
		User result = null;
		Finder finder = Finder.create();
		finder.append("from User u where u.username ='" + username + "'");
		List<User> us = dao.find(finder);
		if (us != null && us.size() > 0) {
			result = us.get(0);
		}
		return result;
	}

	/**
	 * 设定安全的密码，生成随机的salt并经过1024次 sha-1 hash
	 */
	private void entryptPassword(User user) {
		byte[] salt = Digests.generateSalt(SALT_SIZE);
		user.setSalt(Encodes.encodeHex(salt));

		byte[] hashPassword = Digests.sha1(user.getPlainPassword().getBytes(),
				salt, HASH_INTERATIONS);
		user.setPassword(Encodes.encodeHex(hashPassword));
	}

	/**
	 * 验证原密码是否正确
	 * 
	 * @param user
	 * @param oldPwd
	 * @return
	 */
	public boolean checkPassword(User user, String oldPassword) {
		byte[] salt = Encodes.decodeHex(user.getSalt());
		byte[] hashPassword = Digests.sha1(oldPassword.getBytes(), salt,
				HASH_INTERATIONS);
		if (user.getPassword().equals(Encodes.encodeHex(hashPassword))) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 修改用户登录
	 * 
	 * @param user
	 */
	@Transactional
	public User updateUserLogin(User user) {
		user = dao.findById(user.getId());
		user.setLastDate(new Date());
		Integer times = user.getLogintimes();
		if (times == null) {
			times = 0;
		}
		times++;
		user.setLogintimes(times);
		return update(user);
	}

	@Transactional
	@Override
	public User login(String username, String password, String macaddress) {
		User result = null;
		Finder finder = Finder.create();
		finder.append("from User u where u.username ='" + username + "'");
		// finder.append("  and  u.password = '" + password + "'");
		List<User> us = dao.find(finder);
		if (us != null && us.size() > 0) {
			result = us.get(0);
			if (checkPassword(result, password)) {
				result.setMacaddress(macaddress);
				result.setLastDate(new Date());
				Integer logintime = result.getLogintimes();
				if (logintime == null) {
					logintime = 0;
				}
				logintime++;
				result.setLogintimes(logintime);
			} else {
				result = null;
			}

		}
		return result;
	}
}